<?php

class Product extends Tut_Model {

    public $id;
    public $product_category_id;
    public $name;
    public $summary;
    public $description;
    public $image;
    public $level_id;
    public $order;
    public $source;
    public $rate;
    public $total_view;
    public $total_like;
    public $is_actived;
    public $is_featured;
    public $language_id;
    public $meta_title;
    public $meta_keyword;
    public $meta_description;
    public $meta_robot;
    public $new_from;
    public $new_to;
    public $date_show;
    public $date;
    public $last_update;
    public $is_deleted;
    
    public $atag;
    private $_aSort;
    private $_aSearch;
    private $_aRealSort;
    

    public function __construct() {
        parent::__construct();
        $this->_load();
    }

    public function save1() {
        $this->_prepare_save();
        $asave = array(
                'product_category_id' => $this->product_category_id,
                'name' => $this->name,
                'summary' => $this->summary,
                'description' => $this->description,
                //Image should in a table in case of have many picture in.
                'image' => $this->image,
                'source' => $this->source,
                'level_id'   => $this->level_id,
                'order' => $this->order,
                'is_actived' => $this->is_actived,
                'is_featured' => $this->is_featured,
                'language_id' => $this->language_id,
//                'tag'   => $apost['tag'],
                'meta_title' => $this->meta_title,
                'meta_keyword' => $this->meta_keyword,
                'meta_description' => $this->meta_description,
                'meta_robot' => $this->meta_robot,
                'date'  => $this->date,
                'date_show' => $this->date_show,
                'last_update' => $this->last_update,
                'is_deleted'    => $this->is_deleted
            );
        
        if (!$this->id) {
            if ((bool) $this->db->insert('product', $asave)) {
                $iid_product = $this->db->insert_id();
                $this->prepare_tag($this->atag, $iid_product);
                $this->db->insert_batch('tag_product', $this->atag);
                return $asave;
            }
            return false;
        }
        
        //In case update product.
        if ($this->db->update('product', $asave, array('id' => $this->id))) {
            //Delete the old tag.
            $this->load->model('tag', 'tag', false, 'tag');
            
            if($this->tag->delete_by_product_id($this->id)){
                //Update for new tag.
                $this->prepare_tag($this->atag, $this->id);
                $this->db->insert_batch('tag_product', $this->atag);
            }
            return $asave;
        }
    }
    
    public function prepare_tag($atag, $iid_product){
        if(!$atag || !$iid_product){
//            $this->log->
            return false;
        }
        
        $this->load->model('tag', 'tag', false, 'tag');
        //check if item is existed.
        foreach($atag as $tag){
            if(!$this->exist('tag', array('name' => $tag))){
                $this->db->insert('tag', 
                        array('name' => $tag, 'slug' => $this->tag->create_slug($tag), 'created_date' => time(), 'last_update' => time(), 'is_deleted' => 0));
            }
        }
        //Get all id of tags.
        return ($this->atag = $this->tag->get_ids_by_name($atag, $iid_product));
    }

    public function save($iId, $iUserId) {
        if (empty($iId) || empty($iUserId)) {
            return false;
        }

        $aSavedProduct = array(
            'user_id' => $iUserId,
            'product_id' => $iId,
            'date' => time()
        );

        if ((bool) $this->db->insert('saved_product', $aSavedProduct)) {
            return $iId;
        }

        return false;
    }

    public function delete($aIds) {
        if (empty($aIds)) {
            return false;
        }

        $this->db->where_in('id', array_values($aIds));
        $this->db->update('product', array('is_deleted' => 1));

        if ($this->db->affected_rows() > 0) {
            return true;
        }

        return false;
    }

    public function getById($iId = 0, $bIsCheckActive = true) {
        if (empty($iId)) {
            return false;
        }

        $this->db->select('p.*, pc.name as product_category, le.name as level, l.name as language')
                ->from('product as p')
                ->join('product_category as pc', 'p.product_category_id = pc.id')
                ->join('language as l', 'p.language_id = l.id')
                ->join('level le', 'p.level_id = le.id')
                ->where('p.id', $iId);

        if ($bIsCheckActive) {
            $this->db->where('p.is_actived', self::ACTIVE);
        }

        $product = $this->db->get();

        if ($product->num_rows() > 0) {
            $product = $product->row();
            $product->date = date($this->sdate_format, $product->date);
            $this->load->model('tag', 'tag', false, 'tag');
            $atag = $this->tag->get_by_product_id($iId);
            $product = array('tag'=> $atag) + (array)$product;
            return $product;
        }

        return false;
    }

    public function getByCategoryId($iCategoryId, $bIsCheckActive = false) {
        if (empty($iCategoryId)) {
            return false;
        }

        $this->db->select('*')
                ->from('product')
                ->where(array('product_category_id' => $iCategoryId, 'is_deleted' => 0));

        if ($bIsCheckActive) {
            $this->db->where('is_actived', ACTIVE);
        }

        $category = $this->db->get();

        if ($category->num_rows() > 0) {
            $oCategory = $category->result();
            $aCategory = array();
            foreach ($oCategory as $value) {
                $aCategory[] = $value;
            }

            return $aCategory;
        }

        return false;
    }

    public function addImage($sName) {
        if (empty($sName)) {
            return false;
        }

        $aImage = array(
            'name' => $sName,
            'date' => time()
        );

        if ((bool) $this->db->insert('image', $aImage)) {
            return $aImage;
        }

        return false;
    }

    protected function _prepare_save() {
        $this->product_category_id = 1;
        ////////////
        $this->date_show = time();
        
        if(!$this->id){
            $this->date = time();
        }
        
        $this->last_update = time();
        $this->is_deleted = self::UNDELETED;
    }

    public function gets($offset = 0, $numRow = 10, $squery = '') {
        $this->db->select('SQL_CALC_FOUND_ROWS p.id, p.name, p.summary, p.description,
            pc.name as category, p.total_view, p.total_like, p.date, p.image, sp.user_id as user_saved', false)
                ->from('product p')
                ->join('product_category pc', 'p.product_category_id = pc.id', 'left')
                ->join('language l', 'p.language_id = l.id', 'left')
                ->join('saved_product sp', 'p.id = sp.product_id', 'left')
                ->join('level le', 'p.level_id = le.id', 'left')
                ->where(array('p.is_actived' => 1, 'p.is_deleted' => 0))
                ->limit($numRow, $offset)
                ->order_by('order', 'asc');

        if($squery){
            $this->db->or_like(array('p.name' => $squery,
                'p.description' => $squery, 'p.summary' => $squery));
        }
        
        $oProduct = $this->db->get();
        $aProduct = array();
        $this->load->library('encrypt');
        
        if ($oProduct->num_rows() > 0) {
            foreach ($oProduct->result() as $product) {
                $product->date = date('Y-m-d', $product->date);
                //$product->id = $this->encrypt->encode($product->id, $this->config->item('encode_id'));
                $aProduct[] = $product;
            }
        }

        $this->_itotal_rows = $this->db->query('SELECT FOUND_ROWS() AS count', false)->row()->count;

        return $aProduct;
    }

    public function getListAdmin($offset, $aSearch = null) {
        $this->db->select('SQL_CALC_FOUND_ROWS p.id, p.name, pc.name as category, p.date, p.is_actived as actived,
            p.is_featured as featured, p.order, l.name as language,
            le.name as level, p.date', false)
                ->from('product p')
                ->join('product_category pc', 'p.product_category_id = pc.id', 'left')
                ->join('language l', 'p.language_id = l.id', 'left')
                ->join('level le', 'p.level_id = le.id', 'left')
                ->where('p.is_deleted', 0);

        $aSearch = $this->prepareSearch($aSearch);

        foreach ($aSearch as $key => $val) {
            if (trim($val) == '') {
                continue;
            }

            switch ($key) {
                case 'category':
                case 'p.name':
                    $this->db->like($key, $val);
                    break;
                default :
                    $this->db->where($key, $val);
                    break;
            }
        }

        $iLimit = $this->session->userdata(self::ELE_PER_PAGE_ADMIN_SESNAME);

        if (!$iLimit) {
            $iLimit = self::ELE_PER_PAGE_ADMIN;
        }

        $this->db->limit($iLimit, ($offset - 1) * $iLimit);

        foreach ($this->_aSort as $key => $value) {
            $this->db->order_by($this->_aRealSort[$key], $value);
        }

        $oProduct = $this->db->get();
        $aProduct = array();

        if ($oProduct->num_rows() > 0) {
            foreach ($oProduct->result() as $product) {
                $product->date = date('Y-m-d', $product->date);
                $aProduct[] = $product;
            }
        }

        $this->_itotal_rows = $this->db->query('SELECT FOUND_ROWS() AS count', false)->row()->count;

        return $aProduct;
    }

    public function prepareSearch($aSearch = null) {
        if (empty($aSearch)) {
            return array();
        }
        //Prepare search.
        $aReturn = array(
            'p.name' => $aSearch['name'],
            'p.is_actived' => $aSearch['is_actived'],
            'p.is_featured' => $aSearch['featured'],
            'pc.name' => $aSearch['category'],
            'p.order >=' => $aSearch['order']['from'],
            'p.order <=' => $aSearch['order']['to'],
            'p.date >=' => strtotime($aSearch['date']['from']),
            'p.date <=' => strtotime($aSearch['date']['to']),
            'p.language_id' => $aSearch['language'],
            'p.id >=' => $aSearch['id']['from'],
            'p.id <=' => $aSearch['id']['to']
        );

        if ($aSearch['is_actived'] == -1) {
            unset($aReturn['p.is_actived']);
        }

        if ($aSearch['featured'] == -1) {
            unset($aReturn['p.is_featured']);
        }

        if ($aSearch['is_actived'] == -1) {
            unset($aReturn['language_id']);
        }

        if ($aSearch['language'] == -1) {
            unset($aReturn['p.language_id']);
        }

        if (!$aReturn['p.date >=']) {
            unset($aReturn['p.date >=']);
        }

        if (!$aReturn['p.date <=']) {
            unset($aReturn['p.date <=']);
        }

        return $aReturn;
    }

    public function sort($sCol = '') {
        if (empty($sCol)) {
            return false;
        }

        $sTypeSort = $this->prepareSort($sCol);

        if (!$sTypeSort) {
            $this->session->unset_userdata($this->config->item('sort'));
        } else {
            $this->session->set_userdata($this->config->item('sort'), $this->_aSort);
        }

        return $sTypeSort;
    }

    public function prepareSort($sCol) {
        if (empty($sCol)) {
            return false;
        }

        if (empty($this->_aSort[$sCol])) {
            $this->_aSort = array($sCol => 'desc');

            return 'desc';
        } else {
            $sTypeSort = $this->_aSort[$sCol] == 'desc' ? 'asc' : null;

            if (!$sTypeSort) {
                unset($this->_aSort[$sCol]);
            } else {
                $this->_aSort[$sCol] = $sTypeSort;
            }

            return $sTypeSort;
        }

        return false;
    }

    public function getSort() {
        $this->_aSort = $this->session->userdata($this->config->item('sort'));

        if (!(bool) $this->_aSort) {
            return array('order' => 'desc');
        }

        return $this->_aSort;
    }

    public function get_by_search_keyword($skeyword, $ideltra_autocomplete) {
        $this->db->select('p.search_keyword')
                ->from('product p');

        if ($skeyword) {
            $oGet = $this->db->like(array('p.search_keyword' => $skeyword));
        }

        $oGet = $this->db->limit($ideltra_autocomplete)
                ->order_by('p.search_keyword', 'asc')
                ->get();

        $aGet = array();

        if ($oGet->num_rows() > 0) {
            foreach ($oGet->result() as $getObj) {
                $aGet[] = $getObj->search_keyword;
            }
        }

        return $aGet;
    }
    
    public function get_rule() {
        return array(
            array(
                'field' => 'product[name]',
                'label' => $this->lang->line("pharse var='product.name_product'"),
                'rules' => 'trim|required|min_length[5]'
            ),
            array(
                'field' => 'product[order]',
                'label' => $this->lang->line("pharse var='product.order'"),
                'rules' => 'trim|numeric|greater_than[0]'
            ),
            array(
                'field' => 'product[source]',
                'label' => $this->lang->line("pharse var='product.source'"),
                'rules' => 'trim|required|regex_match[#^(http|https):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?(\/)?#i]'
            ),
            array(
                'field' => 'product[level]',
                'label' => $this->lang->line("pharse var='product.level'"),
                'rules' => 'trim|required|numeric|greater_than[0]|less_than[4]'
            ),
            array(
                'field' => 'product[language]',
                'label' => $this->lang->line("pharse var='product.language'"),
                'rules' => 'trim|required|numeric|greater_than[0]|less_than[3]'
            ),
            array(
                'field' => 'product[image]',
                'label' => $this->lang->line("pharse var='product.image'"),
                'rules' => 'trim|required'
            ),
            array(
                'field' => 'product[is_actived]',
                'label' => $this->lang->line("pharse var='product.status'"),
                'rules' => 'trim|required|numeric|greater_than[-1]|less_than[2]'
            ),
            array(
                'field' => 'product[is_featured]',
                'label' => $this->lang->line("pharse var='product.featured'"),
                'rules' => 'trim|required|numeric|greater_than[-1]|less_than[2]'
            ),
            array(
                'field' => 'product[summary]',
                'label' => $this->lang->line("pharse var='product.summary'"),
                'rules' => 'trim|required|min_length[20]'
            ),
            array(
                'field' => 'product[description]',
                'label' => $this->lang->line("pharse var='product.description'"),
                'rules' => 'trim|required'
            ),
            array(
                'field' => 'product[meta_title]',
                'label' => $this->lang->line("pharse var='product.meta_title'"),
                'rules' => 'trim|required'
            ),
            array(
                'field' => 'product[meta_keyword]',
                'label' => $this->lang->line("pharse var='product.meta_keyword'"),
                'rules' => 'trim|required'
            ),
            array(
                'field' => 'product[meta_description]',
                'label' => $this->lang->line("pharse var='product.meta_description'"),
                'rules' => 'trim|required'
            ),
            array(
                'field' => 'product[meta_robot]',
                'label' => $this->lang->line("pharse var='product.meta_robot'"),
                'rules' => 'trim|required'
            )
        );
    }
    
    public function get_validation_error() {
        $aField = array('name', 'order', 'level', 'language', 'status',
            'featured', 'notify', 'description', 'summary', 'meta_title', 'meta_keyword',
            'meta_description', 'meta_robot', 'image', 'source');
        $avalidation_error = array();

        foreach ($aField as $field) {
            $avalidation_error = array_merge($avalidation_error, array("{$field}" => form_error("product[{$field}]")));
        }

        return $avalidation_error;
    }

    private function _load() {
        $this->_aSort = $this->getSort();
        $this->_aRealSort = array('name' => 'p.name', 'is_actived' => 'p.is_actived', 'is_featured' => 'p.is_featured',
            'category' => 'pc.name', 'level' => 'p.level_id', 'order' => 'p.order',
            'date' => 'p.date', 'lang' => 'l.name', 'id' => 'p.id');
    }

}

?>